#include "tree.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char name[][16] = {
    "Program", "ExtdefList", "Extdef", "ExtDecList",
    "Specifier", "StructSpecifier", "OptTag", "Tag",
    "VarDec", "FunDec", "VarList", "ParamDec",
    "CompSt", "StmtList", "Stmt", "DefList",
    "Def", "DecList", "Dec", "Exp",
    "Args", "SEMI", "COMMA", "TYPE",
    "STRUCT", "LC", "RC", "ID",
    "LB", "RB", "LP", "RP",
    "RETURN", "IF", "ELSE", "WHILE",
    "ASSIGNOP", "", "AND", "OR", 
    "RELOP", "PLUS", "MINUS", "STAR",
    "NOT", "DOT", "INT", "FLOAT"
};

Node* createLeaf(int elem, int lineno, char *text) {
    Node* nd = malloc(sizeof(Node));
    nd->elem = elem;
    nd->lineno = lineno;
    switch(elem) {
        case 23:
        case 27:
            nd->strval = malloc(sizeof(char) * strlen(text));
            strcpy(nd->strval, text);
            break;
        case 40:
            nd->strval = malloc(sizeof(char) * strlen(text));
            strcpy(nd->strval, text);
            break;
        case 46:
            if(text[1] == 'x') nd->intval = strtol(text, NULL, 16);
            else if(text[0] == '0') nd->intval = strtol(text, NULL, 8);
            else nd->intval = atoi(text);
            break;
        case 47:
            nd->floatval = atof(text);
            break;
        default:
            break;
    }
    return nd;
}

Node* createNode(int elem, int lineno) {
    Node *nd = malloc(sizeof(Node));
    nd->elem = elem;
    nd->lineno = lineno;
    return nd;
}

void insertChild(Node *pa, Node *ch) {
    pa->ch[pa->cnt++] = ch;
    if (ch != NULL) ch->pa = pa;
}

void printTree(Node *nd, int level) {
    
    int i; char indent[128] = {0};
    for(i = 0; i < level; i++) indent[i] = ' '; indent[i] = '\0';

    printf("%s%s (%d)", indent, name[nd->elem], nd->lineno);

    switch (nd->elem)
    {
        case 23:
        case 27:
            printf(": %s\n", nd->strval);
            break;
        case 46:
            printf(": %d\n", nd->intval);
            break;
        case 47:
            printf(": %lf\n", nd->floatval);
            break;
        default:
            printf("\n");
            break;
    }
    for(i = 0; i < nd->cnt; i++) {
        if(nd->ch[i] == NULL) continue;
        printTree(nd->ch[i], level + 1);
    }
}
